[IOMMU] dynamic VTd page table for HVM guest
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 3 Sep 2009 06:29:29 +0000 (07:29 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 3 Sep 2009 06:29:29 +0000 (07:29 +0100)
This patch makes HVM's VTd page table dynamic just like what PV guest
does, so that avoid the overhead of maintaining page table until a PCI
device is truly assigned to the HVM guest.

Signed-Off-By: Zhai, Edwin <edwin.zhai@intel.com>
xen/arch/ia64/xen/domain.c
xen/arch/ia64/xen/mm.c
xen/arch/x86/mm/hap/p2m-ept.c
xen/arch/x86/mm/p2m.c
xen/drivers/passthrough/amd/iommu_map.c
xen/drivers/passthrough/amd/pci_amd_iommu.c
xen/drivers/passthrough/iommu.c
xen/drivers/passthrough/pci.c
xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
xen/include/xen/sched.h

index 60b20b53639cc565ad9add23783b57e130b3fb6e..854c8b2dee70643ab07c9de30e61f2654275bce2 100644 (file)
@@ -669,7 +669,7 @@ void arch_domain_destroy(struct domain *d)
                free_xenheap_pages(d->shared_info,
                                   get_order_from_shift(XSI_SHIFT));
 
-       if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) )     {
+       if ( iommu_enabled && need_iommu(d) )   {
                pci_release_devices(d);
                iommu_domain_destroy(d);
        }
index de18232388d0882fbb2dda7eccc4476569c02dc0..437ddbca6e1d8bb9b664ad934d844b0298e13a42 100644 (file)
@@ -1479,7 +1479,7 @@ zap_domain_page_one(struct domain *d, unsigned long mpaddr,
     if(!mfn_valid(mfn))
         return;
 
-    if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) ){
+    if ( iommu_enabled && need_iommu(d) ){
         int i, j;
         j = 1 << (PAGE_SHIFT-PAGE_SHIFT_4K);
         for(i = 0 ; i < j; i++)
@@ -2885,7 +2885,7 @@ __guest_physmap_add_page(struct domain *d, unsigned long gpfn,
     smp_mb();
     assign_domain_page_replace(d, gpfn << PAGE_SHIFT, mfn,
                                ASSIGN_writable | ASSIGN_pgc_allocated);
-    if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) ){
+    if ( iommu_enabled && need_iommu(d) ){
         int i, j;
         j = 1 << (PAGE_SHIFT-PAGE_SHIFT_4K);
         for(i = 0 ; i < j; i++)
index 1aa0a6ff376d85bdb5735fe4aee6b9fb628526e6..4a2d81bba1c61549a40ce71038580f58308cae3b 100644 (file)
@@ -282,7 +282,7 @@ out:
     ept_sync_domain(d);
 
     /* Now the p2m table is not shared with vt-d page table */
-    if ( iommu_enabled && is_hvm_domain(d) && need_modify_vtd_table )
+    if ( iommu_enabled && need_iommu(d) && need_modify_vtd_table )
     {
         if ( p2mt == p2m_ram_rw )
         {
index 91b148b2ddd4e61c0187268823bf83e05f177df1..c10b31b566498a54f4c480e9115636b768ef4cc3 100644 (file)
@@ -1199,7 +1199,7 @@ p2m_set_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
          && (gfn + (1UL << page_order) - 1 > d->arch.p2m->max_mapped_pfn) )
         d->arch.p2m->max_mapped_pfn = gfn + (1UL << page_order) - 1;
 
-    if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) )
+    if ( iommu_enabled && need_iommu(d) )
     {
         if ( p2mt == p2m_ram_rw )
             for ( i = 0; i < (1UL << page_order); i++ )
index 3d051d4696631a282437c803a6eaba439d9d9cc1..9754f4b1ed386fdf815fd0271169ceaf64b1b41c 100644 (file)
@@ -555,58 +555,6 @@ int amd_iommu_reserve_domain_unity_map(
     return 0;
 }
 
-int amd_iommu_sync_p2m(struct domain *d)
-{
-    unsigned long mfn, gfn;
-    u64 iommu_l2e;
-    struct page_info *page;
-    struct hvm_iommu *hd;
-    int iw = IOMMU_IO_WRITE_ENABLED;
-    int ir = IOMMU_IO_READ_ENABLED;
-
-    if ( !is_hvm_domain(d) )
-        return 0;
-
-    hd = domain_hvm_iommu(d);
-
-    spin_lock(&hd->mapping_lock);
-
-    if ( hd->p2m_synchronized )
-        goto out;
-
-    spin_lock(&d->page_alloc_lock);
-
-    page_list_for_each ( page, &d->page_list )
-    {
-        mfn = page_to_mfn(page);
-        gfn = get_gpfn_from_mfn(mfn);
-
-        if ( gfn == INVALID_M2P_ENTRY )
-            continue;
-
-        iommu_l2e = iommu_l2e_from_pfn(hd->root_table, hd->paging_mode, gfn);
-
-        if ( iommu_l2e == 0 )
-        {
-            spin_unlock(&d->page_alloc_lock);
-            spin_unlock(&hd->mapping_lock);
-            amd_iov_error("Invalid IO pagetable entry gfn = %lx\n", gfn);
-            domain_crash(d);
-            return -EFAULT;
-        }
-
-        set_iommu_l1e_present(iommu_l2e, gfn, (u64)mfn << PAGE_SHIFT, iw, ir);
-    }
-
-    spin_unlock(&d->page_alloc_lock);
-
-    hd->p2m_synchronized = 1;
-
-out:
-    spin_unlock(&hd->mapping_lock);
-    return 0;
-}
-
 void invalidate_all_iommu_pages(struct domain *d)
 {
     u32 cmd[4], entry;
index 7ab82d9912a37c6fc589040472da36f2298c8ee5..70683d24e27ff82d06a578d7576784022e147cfa 100644 (file)
@@ -311,8 +311,6 @@ static int amd_iommu_assign_device(struct domain *d, u8 bus, u8 devfn)
     int bdf = (bus << 8) | devfn;
     int req_id = ivrs_mappings[bdf].dte_requestor_id;
 
-    amd_iommu_sync_p2m(d);
-
     if ( ivrs_mappings[req_id].unity_map_enable )
     {
         amd_iommu_reserve_domain_unity_map(
index b0dd91d66c7b28dba5b152e64771980b68855e20..6933e658fe9b319569b5b38d531b2f33721964b3 100644 (file)
@@ -137,7 +137,7 @@ int assign_device(struct domain *d, u8 bus, u8 devfn)
     if ( (rc = hd->platform_ops->assign_device(d, bus, devfn)) )
         goto done;
 
-    if ( has_arch_pdevs(d) && !is_hvm_domain(d) && !need_iommu(d) )
+    if ( has_arch_pdevs(d) && !need_iommu(d) )
     {
         d->need_iommu = 1;
         rc = iommu_populate_page_table(d);
@@ -184,7 +184,7 @@ void iommu_domain_destroy(struct domain *d)
     if ( !iommu_enabled || !hd->platform_ops )
         return;
 
-    if ( !is_hvm_domain(d) && !need_iommu(d)  )
+    if ( !need_iommu(d)  )
         return;
 
     if ( need_iommu(d) )
index bf47ae97b85eea8b14df09cc7c8f184adccf74d2..843324598bfeae4798991396eebcf8ddc6e97bfb 100644 (file)
@@ -202,7 +202,7 @@ static void pci_clean_dpci_irqs(struct domain *d)
     if ( !iommu_enabled )
         return;
 
-    if ( !is_hvm_domain(d) && !need_iommu(d) )
+    if ( !need_iommu(d) )
         return;
 
     spin_lock(&d->event_lock);
index 9d1ef04097a0e02493079d2a3ef3e856dd96d8f7..3e972cf655d0d16852ae110bb6057ff5695a3b3d 100644 (file)
@@ -63,7 +63,6 @@ int amd_iommu_unmap_page(struct domain *d, unsigned long gfn);
 u64 amd_iommu_get_next_table_from_pte(u32 *entry);
 int amd_iommu_reserve_domain_unity_map(struct domain *domain,
         unsigned long phys_addr, unsigned long size, int iw, int ir);
-int amd_iommu_sync_p2m(struct domain *d);
 void invalidate_all_iommu_pages(struct domain *d);
 
 /* device table functions */
index be15f3307f75b33585f047f52c3285db0e7694fa..d37c83fccb532369acf20dd2d65bcfeb20ef9e48 100644 (file)
@@ -557,7 +557,7 @@ uint64_t get_cpu_idle_time(unsigned int cpu);
 
 #define is_hvm_domain(d) ((d)->is_hvm)
 #define is_hvm_vcpu(v)   (is_hvm_domain(v->domain))
-#define need_iommu(d)    ((d)->need_iommu && !(d)->is_hvm)
+#define need_iommu(d)    ((d)->need_iommu)
 
 void set_vcpu_migration_delay(unsigned int delay);
 unsigned int get_vcpu_migration_delay(void);